package com.iriscouch.gwtapp.client;

import com.google.gwt.core.client.JavaScriptObject;
import org.timepedia.exporter.client.Export;
import org.timepedia.exporter.client.NoExport;
import org.timepedia.exporter.client.Exportable;
import org.timepedia.exporter.client.ExportPackage;

@ExportPackage("bigdecimal")
@Export
public class BigDecimal extends java.math.BigDecimal implements Exportable {
  // I think this constructor is needed for Javascript compatibility.
  public BigDecimal() {
    super("0");
  }

  @NoExport
  public BigDecimal(java.math.BigDecimal source) {
    super(source.toString());
  }

  // Use a class method to wrap the constructor.
  public static BigDecimal __init__(JsArgs args) {
    java.math.BigDecimal obj;
    <%= call_signatures 'args', 'obj = new java.math.BigDecimal',
      "BigInteger",
      "BigInteger int",
      "BigInteger int MathContext",
      "BigInteger MathContext",
      "char_array",
      "char_array int int",
      "char_array int int MathContext",
      "char_array MathContext",
      "double",
      "double MathContext",
      "string",
      "string MathContext",
    %>
    return new BigDecimal(obj);
  }

  <%= wrap :BigDecimal, :abs, '', 'MathContext' %>
  <%= wrap :BigDecimal, :add, 'BigDecimal', 'BigDecimal MathContext' %>
  <%= wrap :byte, :byteValueExact %>
  <%= wrap :int, :compareTo, :BigDecimal %>
  <%= wrap :BigDecimal, :divide, 'BigDecimal', 'BigDecimal int', 'BigDecimal int int', 'BigDecimal int RoundingMode', 'BigDecimal MathContext', 'BigDecimal RoundingMode' %>
  <%= wrap :BigDecimal, :divideToIntegralValue, 'BigDecimal', 'BigDecimal MathContext' %>
  <%= wrap :double, :doubleValue %>
  <%= wrap :boolean, :equals, :Object %>
  <%= wrap :float, :floatValue %>
  <%= wrap :int, :hashCode %>
  <%= wrap :int, :intValue %>
  <%= wrap :int, :intValueExact %>
  <%= wrap :BigDecimal, :max, :BigDecimal %>
  <%= wrap :BigDecimal, :min, :BigDecimal %>
  <%= wrap :BigDecimal, :movePointLeft, :int %>
  <%= wrap :BigDecimal, :movePointRight, :int %>
  <%= wrap :BigDecimal, :multiply, 'BigDecimal', 'BigDecimal MathContext' %>
  <%= wrap :BigDecimal, :negate, '', 'MathContext' %>
  <%= wrap :BigDecimal, :plus, '', 'MathContext' %>
  <%= wrap :BigDecimal, :pow, 'int', 'int MathContext' %>
  <%= wrap :int, :precision %>
  <%= wrap :BigDecimal, :remainder, 'BigDecimal', 'BigDecimal MathContext' %>
  <%= wrap :BigDecimal, :round, :MathContext %>
  <%= wrap :int, :scale %>
  <%= wrap :BigDecimal, :scaleByPowerOfTen, :int %>
  <%= wrap :BigDecimal, :setScale, 'int', 'int int', 'int RoundingMode' %>
  <%= wrap :short, :shortValueExact %>
  <%= wrap :int, :signum %>
  <%= wrap :BigDecimal, :stripTrailingZeros %>
  <%= wrap :BigDecimal, :subtract, 'BigDecimal', 'BigDecimal MathContext' %>
  <%= wrap :BigInteger, :toBigInteger %>
  <%= wrap :BigInteger, :toBigIntegerExact %>
  <%= wrap :String, :toEngineeringString %>
  <%= wrap :String, :toPlainString %>
  <%= wrap :String, :toString %>
  <%= wrap :BigDecimal, :ulp %>
  <%= wrap :BigInteger, :unscaledValue %>

  public BigDecimal[] divideAndRemainder_va(JsArgs args) {
    java.math.BigDecimal[] interim;
    <%= call_signatures 'args', 'interim = super.divideAndRemainder', 'BigDecimal', 'BigDecimal MathContext' %>

    BigDecimal[] result = new BigDecimal[interim.length];
    for(int a = 0; a < interim.length; a++)
      result[a] = new BigDecimal(interim[a]);
    return result;
  }

  @Export("longValue")
  public double longValue_wrap() { return doubleValue(); }

  @Export("longValueExact")
  public int longValueExact_wrap() { return intValueExact(); }

  public static final BigDecimal valueOf_va(JsArgs args) {
    java.math.BigDecimal bd;
    <%= call_signatures 'args', 'bd = java.math.BigDecimal.valueOf', 'double', 'int', 'int int' %> <%# XXX long type is not allowed %>
    return new BigDecimal(bd);
  }

  public static native void log(String x) /*-{
    require("sys").puts(x);
  }-*/;

  public static native void logObj(JavaScriptObject x) /*-{
    require("sys").puts("object: " + require("sys").inspect(x));
  }-*/;

  // Fields
  <% %w[ ROUND_CEILING ROUND_DOWN ROUND_FLOOR ROUND_HALF_DOWN ROUND_HALF_EVEN ROUND_HALF_UP ROUND_UNNECESSARY ROUND_UP ].each do |field| %>
    public static final int <%= field %> = java.math.BigDecimal.<%= field %>;
  <% end %>

  // TODO: Make these actual fields
  <% %w[ ONE TEN ZERO ].each do |field| %>
    public static final BigDecimal <%= field %>() { return new BigDecimal(java.math.BigDecimal.<%= field %>); }
  <% end %>
}
